package server.connector;

import server.connector.http.HttpResponse;

import javax.servlet.ServletOutputStream;
import java.io.IOException;
import java.io.OutputStream;

//强制写的字节数不会超过length
//如果length<=0,不限制写的长度
//当commit为false时,flush不会刷新缓冲区,缓冲区满或关闭流时会刷新
public class ResponseStream extends ServletOutputStream {
    protected boolean closed = false;
    protected boolean commit = false;
    protected int count = 0;
    protected int length = -1;
    protected HttpResponse response = null;
    public ResponseStream(HttpResponse response) {
        super();
        closed = false;
        commit = false;
        count = 0;
        this.response = response;
    }
    protected OutputStream stream = null;

    @Override
    public void close() throws IOException {
        if (closed)
            throw new IOException("responseStream.close.closed");
        response.flushBuffer();
        closed = true;
    }

    @Override
    public void flush() throws IOException {
        if (closed)
            throw new IOException("responseStream.flush.closed");
        if (commit)
            response.flushBuffer();
    }

    @Override
    public void write(int b) throws IOException {
        if (closed)
            throw new IOException("responseStream.write.closed");
        //写够长度了，不能再写
        if (length > 0 && count >= length)
            throw new IOException("responseStream.write.count");
        response.write(b);
        count++;
    }

    @Override
    public void write(byte[] b) throws IOException {
        write(b, 0, b.length);
    }

    @Override
    public void write(byte[] b, int off, int len) throws IOException {
        if (closed)
            throw new IOException("responseStream.write.closed");
        int wLen = len;
        if (length > 0 && count + len > length) {
            wLen = length - count;
        }
        response.write(b, off, wLen);
        count += wLen;
        if (wLen < len) {
            throw new IOException("responseStream.write.count");
        }
    }



    //getter
    public boolean getCommit() {
        return commit;
    }

    boolean closed() {
        return closed;
    }
    void reset() {
        count = 0;
    }
    //setter
    public void setCommit(boolean commit) {
        this.commit = commit;
    }

}
